import React, { Component } from 'react';
import {
  Modal,
  Form,
  Input,
  Select,
  Checkbox,
  Switch,
  message,
  Cascader,
  Radio,
  Icon,
  Tooltip,
  Button
} from 'antd';
import { updateSystemConfig, checkLdapConnection, updateLDAPDataByHand } from '@api/system';
import cn from 'classnames';
import './index.less';
import FormItem from 'antd/lib/form/FormItem';
import _ from 'lodash';
import PropTypes from 'prop-types';
import { PERSON_CLASS_TIP, ORG_CLASS_TIP, BELONG_ORG_TIP, UPDATE_METHOD_TIP } from './constant';

const FromItem = Form.Item;

const formItemLayout = {
  labelCol: {
    xs: { span: 24 },
    sm: { span: 6 }
  },
  wrapperCol: {
    xs: { span: 24 },
    sm: { span: 18 }
  }
};

const LdapSelector = props => {
  return (
    <Select {...props}>
      <Select.Option key="LDAP">LDAP服务器</Select.Option>
      <Select.Option key="ADDS">活动目录服务器(AD)</Select.Option>
    </Select>
  );
};

class AutoSyncLdapModal extends Component {
  static propTypes = {
    visible: PropTypes.bool,
    form: PropTypes.object,
    onCancel: PropTypes.func,
    onCallback: PropTypes.func,
    LdapConfig: PropTypes.object,
    cascaderTree: PropTypes.array
  };
  static treePruning = (rawTree = [], rawPaths = [], id) => {
    if (!id) {
      return _.cloneDeep(rawTree);
    }
    let tree = _.cloneDeep(rawTree),
      paths = _.cloneDeep(rawPaths);
    let tmpChildren = tree;
    while (tmpChildren.length && paths.length) {
      let current = paths.shift();
      let tmpParent = _.find(tmpChildren, i => _.get(i, '_id') === current);
      tmpChildren = _.get(tmpParent, 'children', []);
    }
    let currentIndex = _.findIndex(tmpChildren, i => _.get(i, '_id') === id);
    tmpChildren.splice(currentIndex, 1);
    return tree;
  };

  static getStateFromProps = props => {
    const LdapConfigFromProps = props.LdapConfig
      ? props.LdapConfig
      : {
          isSSL: false,
          update: {}
        };
    let { isSSL = false, update = {}, parentOrgPath } = LdapConfigFromProps;

    let {
      // eslint-disable-next-line
      _id: id = '',
      // eslint-disable-next-line
      parent_oid: parentId = '',
      name = ''
    } = _.get(props, 'currentOrg', {});
    let rawCascaderTree = _.get(props, 'cascaderTree', []);
    let cascaderTree = AutoSyncLdapModal.treePruning(rawCascaderTree, [], id);
    return {
      useSSL: isSSL,
      interval: _.get(update, 'interval', 1),
      updateStatus: _.get(update, 'isOpen', false),
      cascaderTree,
      paths: parentOrgPath,
      id: id,
      name,
      parentId
    };
  };

  constructor(props) {
    super(props);
    this.state = {
      ...AutoSyncLdapModal.getStateFromProps(props)
    };
  }

  // eslint-disable-next-line
  UNSAFE_componentWillReceiveProps(nextProps) {
    if (
      (!this.props.visible && nextProps.visible) ||
      this.props.cascaderTree !== nextProps.cascaderTree
    ) {
      this.setState({
        ...AutoSyncLdapModal.getStateFromProps(nextProps)
      });
    }
  }
  //  更新数据
  submit = flage => {
    const {
      form: { validateFieldsAndScroll }
    } = this.props;
    const { updateStatus, interval, useSSL, paths } = this.state;
    const { onCancel } = this.props;
    validateFieldsAndScroll((err, values) => {
      if (!err) {
        _.set(values, 'update.isOpen', updateStatus);
        _.set(values, 'update.interval', interval);
        _.set(values, 'isSSL', useSSL);
        _.set(values, 'parentOrgOid', paths[paths.length - 1]);
        updateSystemConfig({
          type: 'LDAP',
          param: values
        })
          .then(res => {
            this.props.onCallback({
              LdapConfig: { ..._.get(res, 'data.data.systemConfig', {}), parentOrgPath: paths }
            });
            if (res.data.result) {
              onCancel();
              // 手动触发同步
              if (flage) {
                message.success('数据已在后台更新，请5分钟后在组织架构这里查看更新后到数据');
                this.handleUpdateLdapOnce();
              } else {
                message.success('保存成功');
              }
            } else {
              message.error('更新数据失败');
            }
          })
          .catch(err => {
            message.error(err.message || '更新数据失败');
          });
      }
    });
  };

  // 测试是否连接成功
  checkLdapConn = (e, flage = false) => {
    e.preventDefault();
    const {
      form: { validateFieldsAndScroll }
    } = this.props;
    const { useSSL } = this.state;
    validateFieldsAndScroll((err, values) => {
      if (!err) {
        _.set(values, 'isSSL', useSSL);
        const body = {
          serverType: values.serverType,
          ip: values.ip,
          port: values.port,
          isSSL: values.isSSL,
          username: values.username,
          password: values.password,
          rootDN: values.rootDN,
          pem: values.pem
        };
        checkLdapConnection(body).then(res => {
          if (res.data.data.status) {
            this.submit(flage);
          } else {
            message.error('连接失败!');
          }
        });
      }
    });
  };

  handleIntervalChange = e => {
    let interval = e.target.value;
    interval < 1 && (interval = 1);
    this.setState({ interval });
  };

  onParentChange = path => {
    this.setState({ paths: path });
  };

  makeLabelWithTip = (label, tip = '') => {
    return (
      <Tooltip title={tip} trigger="hover" overlayClassName="ldap-tooltip-overlay">
        {label}&nbsp;
        <Icon type="info-circle" />
      </Tooltip>
    );
  };

  handleUpdateLdapOnce = () => {
    updateLDAPDataByHand().then(res => {
      if (_.get(res, 'data.data.result', '') === 'ok') {
        message.success('同步成功!');
      } else {
        message.error('同步失败!');
      }
    });
  };

  renderModalFooter = () => {
    const { onCancel } = this.props;
    return (
      <div>
        <div>
          <Button onClick={() => onCancel()}>取消</Button>
          <Button onClick={e => this.checkLdapConn(e)}>保存</Button>
          <Button type="primary" onClick={e => this.checkLdapConn(e, true)}>
            保存并更新数据
          </Button>
        </div>
      </div>
    );
  };

  render() {
    const { getFieldDecorator } = this.props.form;
    const { visible, onCancel, LdapConfig } = this.props;
    const { useSSL, interval, updateStatus, paths, cascaderTree } = this.state;
    // 初始值填充
    const initalType = _.get(LdapConfig, 'serverType', 'LDAP');
    const initalIp = _.get(LdapConfig, 'ip', '');
    const initalUname = _.get(LdapConfig, 'username', '');
    const initalPort = _.get(LdapConfig, 'port', '');
    const initalPhone = _.get(LdapConfig, 'fieldMapping.phone', '');
    const initalEmail = _.get(LdapConfig, 'fieldMapping.email', '');
    const initalJob = _.get(LdapConfig, 'fieldMapping.job', '');
    const initalRootDn = _.get(LdapConfig, 'rootDN', '');
    const initalPersonClass = _.get(LdapConfig, 'personClass', '');
    const initalOrganizationClass = _.get(LdapConfig, 'organizationClass', '');
    const initalMode = _.get(LdapConfig, 'update.mode', 'full');
    const initalPem = _.get(LdapConfig, 'pem', '');

    return (
      <Modal
        maskClosable={false}
        title="自动同步配置"
        onCancel={onCancel}
        visible={visible}
        className={cn('org-c-auto-sync-modal')}
        footer={this.renderModalFooter()}
      >
        <Form {...formItemLayout}>
          <FromItem label="类型" required>
            {getFieldDecorator('serverType', {
              initialValue: initalType,
              rules: [
                {
                  required: true,
                  message: '请选择类型'
                }
              ]
            })(<LdapSelector />)}
          </FromItem>
          <FromItem label="服务器地址" required>
            {getFieldDecorator('ip', {
              initialValue: initalIp,
              rules: [
                {
                  required: true,
                  message: '请输入服务器地址'
                }
              ]
            })(<Input placeholder="请输入服务器地址" />)}
          </FromItem>
          <FromItem label="端口号" required>
            <div style={{ display: 'flex', alignItems: 'center' }}>
              <FromItem style={{ flex: '.7', marginRight: 10, marginBottom: 0 }}>
                {getFieldDecorator('port', {
                  initialValue: initalPort,
                  rules: [
                    {
                      required: true,
                      message: '请输入端口号'
                    }
                  ]
                })(<Input placeholder="请输入端口号" />)}
              </FromItem>
              <Checkbox checked={useSSL} onChange={() => this.setState({ useSSL: !useSSL })}>
                Use SSL
              </Checkbox>
            </div>
          </FromItem>
          {useSSL ? (
            <FromItem label="证书" required>
              {getFieldDecorator('pem', {
                initialValue: initalPem,
                rules: [
                  {
                    required: true,
                    message: '请输入证书内容'
                  }
                ]
              })(<Input.TextArea placeholder="请输入证书内容" />)}
            </FromItem>
          ) : null}

          <FromItem label="服务器用户名" required>
            {getFieldDecorator('username', {
              initialValue: initalUname,
              rules: [
                {
                  required: true,
                  message: '请输入服务器用户名'
                }
              ]
            })(<Input placeholder="请输入服务器用户名" />)}
          </FromItem>
          <FromItem label="服务器密码" required>
            {getFieldDecorator('password', {
              rules: [
                {
                  required: true,
                  message: '请输入服务器密码'
                }
              ]
            })(<Input type="password" placeholder="请输入服务器密码" />)}
          </FromItem>
          <FromItem label="base DN" required>
            {getFieldDecorator('rootDN', {
              initialValue: initalRootDn,
              rules: [
                {
                  required: true,
                  message: '请输入Root DN'
                }
              ]
            })(<Input type="text" placeholder="请输入Root DN" />)}
          </FromItem>
          <FromItem label={this.makeLabelWithTip('用户标识', PERSON_CLASS_TIP)} required>
            {getFieldDecorator('personClass', {
              initialValue: initalPersonClass,
              rules: [
                {
                  required: true,
                  message: '请输入用户标识'
                }
              ]
            })(<Input type="text" placeholder="请输入角色标识" />)}
          </FromItem>
          <FormItem label={this.makeLabelWithTip('组织标识', ORG_CLASS_TIP)} required>
            {getFieldDecorator('organizationClass', {
              initialValue: initalOrganizationClass,
              rules: [
                {
                  required: true,
                  message: '请输入组织标识'
                }
              ]
            })(<Input type="text" placeholder="请输入组织标识" />)}
          </FormItem>
          <FormItem label={this.makeLabelWithTip('所属部门', BELONG_ORG_TIP)}>
            {getFieldDecorator('paths', {
              rules: [
                {
                  required: true,
                  message: '请输入所属部门'
                }
              ]
            })(
              <Cascader
                value={paths}
                options={cascaderTree}
                changeOnSelect
                onChange={this.onParentChange}
                fieldNames={{ label: 'name', value: '_id', children: 'children' }}
              />
            )}
          </FormItem>
          <FromItem label="手机号标识">
            {getFieldDecorator('fieldMapping.phone', {
              initialValue: initalPhone
            })(<Input placeholder="手机号字段名称" />)}
          </FromItem>
          <FromItem label="邮箱标识">
            {getFieldDecorator('fieldMapping.email', {
              initialValue: initalEmail
            })(<Input placeholder="邮箱字段名称" />)}
          </FromItem>
          <FromItem label="岗位标识">
            {getFieldDecorator('fieldMapping.job', {
              initialValue: initalJob
            })(<Input placeholder="岗位字段名称" />)}
          </FromItem>
          <FromItem label="组织架构更新">
            <div style={{ display: 'flex', alignItems: 'center' }}>
              <Switch
                style={{ marginRight: 10 }}
                checked={updateStatus}
                onChange={() => this.setState({ updateStatus: !updateStatus })}
              />
              <Input
                style={{ flex: '1' }}
                addonAfter="天"
                type="number"
                value={interval}
                onChange={e => this.handleIntervalChange(e)}
              />
            </div>
          </FromItem>
          <FromItem label={this.makeLabelWithTip('更新方式', UPDATE_METHOD_TIP)}>
            {getFieldDecorator('update.mode', {
              initialValue: initalMode
            })(
              <Radio.Group>
                <Radio value="full">全量更新</Radio>
                <Radio value="increment">增量更新</Radio>
              </Radio.Group>
            )}
          </FromItem>
        </Form>
      </Modal>
    );
  }
}

export default Form.create()(AutoSyncLdapModal);
